package com.sumer.psychology.photo.domain.model;

import com.sumer.psychology.common.Assert;
import com.sumer.psychology.common.domain.model.Author;
import com.sumer.psychology.common.domain.model.ConcurrencySafeEntity;

import java.util.Date;

/**
 * 相片
 * <p/>
 * User: zhenguang.zhu
 * Date: 2014/8/29
 * Time: 11:17
 */
public class Photo extends ConcurrencySafeEntity {
    private PhotoId photoId;
    private String title;
    private String description;
    private String fileId;
    private AlbumId albumId;
    private Date createTime;
    private Date lastModifyTime;
    private PhotoAvailability availability;
    private Author owner;

    /**
     * 创建相片
     *
     * @param photoId     id
     * @param title       title
     * @param description desc
     * @param fileId      file
     * @param albumId     album
     * @param owner       owner
     */
    public Photo(PhotoId photoId, String title, String description, String fileId, AlbumId albumId, Author owner) {
        setPhotoId(photoId);
        setTitle(title);
        setDescription(description);
        setFileId(fileId);
        setAlbumId(albumId);
        setCreateTime(new Date());
        setAvailability(PhotoAvailability.ACTIVE);
        setOwner(owner);

        apply(new PhotoUploadedEvent(
                photoId(),
                title(),
                description(),
                fileId(),
                albumId(),
                owner()));
    }

    public Photo() {
    }

    /**
     * 编辑照片 (标题和描述)
     *
     * @param newTitle       title
     * @param newDescription desc
     */
    public void changeTitleAndDescription(String newTitle, String newDescription) {
        setTitle(newTitle);
        setDescription(newDescription);
        setLastModifyTime(new Date());

        apply(new PhotoChangedEvent(
                photoId(),
                title(),
                description()));
    }

    /**
     * 分配到一个新的相册
     *
     * @param albumId album
     */
    public void assignInto(AlbumId albumId) {
        if (!albumId().equals(albumId)) {
            setAlbumId(albumId);
            setLastModifyTime(new Date());

            apply(new PhotoPutToAlbumEvent(
                    photoId(),
                    albumId()));
        }
    }

    /**
     * 删除照片
     */
    public void delete() {
        setAvailability(PhotoAvailability.DELETED);
        setLastModifyTime(new Date());

        apply(new PhotoDeletedEvent(photoId()));
    }

    private void setPhotoId(PhotoId photoId) {
        Assert.notNull(photoId, "id不能为空");
        Assert.notEmpty(photoId.identity(), "id不能为空");

        this.photoId = photoId;
    }

    private void setTitle(String title) {
        Assert.notEmpty(title, "标题不能为空");
        Assert.length(title, 100, "标题不能超过50个字");

        this.title = title;
    }

    private void setDescription(String description) {
        Assert.length(description, 200, "描述不能超过100个字");

        this.description = description;
    }

    private void setFileId(String fileId) {
        Assert.notEmpty(fileId, "file id不能为空");

        this.fileId = fileId;
    }

    private void setAlbumId(AlbumId albumId) {
        Assert.notNull(albumId, "相册不能为空");
        Assert.notEmpty(albumId.identity(), "相册id不能为空");

        this.albumId = albumId;
    }

    private void setCreateTime(Date createTime) {
        Assert.notNull(createTime, "创建日期不能为空");

        this.createTime = createTime;
    }

    private void setLastModifyTime(Date lastModifyTime) {
        this.lastModifyTime = lastModifyTime;
    }

    private void setAvailability(PhotoAvailability availability) {
        Assert.notNull(availability, "状态不能为空");

        this.availability = availability;
    }

    private void setOwner(Author owner) {
        Assert.notNull(owner, "照片所有者不能为空");
        Assert.notEmpty(owner.identity(), "照片所有者不能为空");

        this.owner = owner;
    }

    public PhotoId photoId() {
        return photoId;
    }

    public String title() {
        return title;
    }

    public String description() {
        return description;
    }

    public String fileId() {
        return fileId;
    }

    public AlbumId albumId() {
        return albumId;
    }

    public Date createTime() {
        return createTime;
    }

    public Date lastModifyTime() {
        return lastModifyTime;
    }

    public PhotoAvailability availability() {
        return availability;
    }

    public Author owner() {
        return owner;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Photo photo = (Photo) o;

        if (albumId != null ? !albumId.equals(photo.albumId) : photo.albumId != null) return false;
        if (availability != photo.availability) return false;
        if (description != null ? !description.equals(photo.description) : photo.description != null) return false;
        if (fileId != null ? !fileId.equals(photo.fileId) : photo.fileId != null) return false;
        if (owner != null ? !owner.identity().equals(photo.owner.identity()) : photo.owner != null) return false;
        if (photoId != null ? !photoId.equals(photo.photoId) : photo.photoId != null) return false;
        if (title != null ? !title.equals(photo.title) : photo.title != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = photoId != null ? photoId.hashCode() : 0;
        result = 31 * result + (title != null ? title.hashCode() : 0);
        result = 31 * result + (description != null ? description.hashCode() : 0);
        result = 31 * result + (fileId != null ? fileId.hashCode() : 0);
        result = 31 * result + (albumId != null ? albumId.hashCode() : 0);
        result = 31 * result + (availability != null ? availability.hashCode() : 0);
        result = 31 * result + (owner != null ? owner.identity().hashCode() : 0);
        return result;
    }

    @Override
    public String toString() {
        return "Photo{" +
                "photoId=" + photoId +
                ", title='" + title + '\'' +
                ", description='" + description + '\'' +
                ", fileId='" + fileId + '\'' +
                ", albumId=" + albumId +
                ", createTime=" + createTime +
                ", lastModifyTime=" + lastModifyTime +
                ", availability=" + availability +
                ", owner=" + owner +
                '}';
    }

}
